﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using TD.TheGame;

namespace TD.Interface.Controls
{
    /// <summary>
    /// Represents a state in which the item can reside.
    /// </summary>
    public enum ItemState : int
    {
        /// <summary>
        /// The item is not yet available to the player, it is being unlocked in a later stage.
        /// </summary>
        Locked = 0x00,

        /// <summary>
        /// The item has already been bought by the player.
        /// </summary>
        Bought = 0x01,

        /// <summary>
        /// The item is available in the shop, the player can buy it.
        /// </summary>
        Available = 0x02
    }

    internal class ShopItem : ButtonBase
    {
        private string hint;
        public string Hint { get { return this.hint; } }

        private int price;
        public int Price { get { return this.price; } }

        private Age unlockedAt;
        public Age UnlockedAt { get { return this.unlockedAt; } }

        public ItemState State { get; set; }
        private SpriteBatch spriteBatch;
        private Texture2D locked;
        private Texture2D bought;
        private Texture2D item;
        private string assetName;

        private bool previousFocus;

        public ShopItem(Game1 game, string assetName, Point point, string hint, int price, ItemState state) :
            this(game, assetName, point, hint, price, state, Age.Past)
        {
            // Do something...
        }

        public ShopItem(Game1 game, string assetName, Point point, string hint, int price, ItemState state, Age unlockedAt) :
            this(game, ("interface\\shop\\" + assetName), point, hint, price)
        {
            this.State = state;
            this.unlockedAt = unlockedAt;
        }

        public ShopItem(Game1 game, string assetName, Point point, string hint, int price) :
            base(game, "interface\\shop\\shop_buttons", point, string.Empty, Vector2.Zero)
        {
            this.assetName = assetName;
            this.DrawOrder = 0x08A00001;
            this.State = ItemState.Locked;
            this.hint = hint;
            this.price = price;
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            ((Game1)Game).TextureManager.LoadAsset("interface\\shop\\shop_locked");
            ((Game1)Game).TextureManager.LoadAsset("interface\\shop\\shop_own");
            ((Game1)Game).TextureManager.LoadAsset(assetName);

            locked = ((Game1)Game).TextureManager.UseAsset("interface\\shop\\shop_locked");
            bought = ((Game1)Game).TextureManager.UseAsset("interface\\shop\\shop_own");
            item = ((Game1)Game).TextureManager.UseAsset(assetName);
            
            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            DisposeTexture(ref locked);
            DisposeTexture(ref bought);
            DisposeTexture(ref item);
            
            base.UnloadContent();
        }
        private void DisposeTexture(ref Texture2D texture)
        {
            if (texture != null)
            {
                texture.Dispose();
                texture = null;
            }
        }

        protected override void Modifiers(GameTime gameTime)
        {
            // Do something...
        }

        public override void Update(GameTime gameTime)
        {
            if (State == ItemState.Available)
            {
                base.Update(gameTime);
            }

            if (previousFocus != HasFocus)
            {
                previousFocus = HasFocus;

                if (HasFocus)
                {
                    Hover();
                }
                else
                {
                    Leave();
                }
            }
        }

        protected override void Click()
        {
            State = ItemState.Bought;
            Leave();
            base.Click();
        }

        public override void Draw(GameTime gameTime)
        {
            if (State == ItemState.Available)
            {
                base.Draw(gameTime);
            }
            else
            {
                Texture2D texture = (State == ItemState.Locked ? locked : bought);

                spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied);
                spriteBatch.Draw(texture, new Rectangle(Point.X, Point.Y, texture.Width, texture.Height), Color.White);
                spriteBatch.End();
            }

            if (State != ItemState.Locked)
            {
                spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied);
                spriteBatch.Draw(item, new Rectangle(Point.X + 6, Point.Y + 6, 80, 80), Color.White);
                spriteBatch.End();
            }
        }

        public void Enable()
        {
            if (State == ItemState.Locked)
            {
                State = ItemState.Available;
            }
        }

        public event OnHover MouseHover;
        public delegate void OnHover(object sender);
        protected virtual void Hover()
        {
            if (MouseHover != null)
            {
                MouseHover(this);
            }
        }

        public event OnLeave MouseLeave;
        public delegate void OnLeave(object sender);
        protected virtual void Leave()
        {
            if (MouseLeave != null)
            {
                MouseLeave(this);
            }
        }

        protected override void PlaySound()
        {
            //base.PlaySound();
        }
    }
}
